﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Globalization;
using System.ComponentModel;

namespace Pixysoft.Tools
{
    public class ParserHelper
    {
        /// <summary>
        /// 获取数据类型
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static DotNetDataType GetDataType(object input)
        {
            if (input == null)
                return DotNetDataType.UNKNOWN;

            Type type = input.GetType();

            return GetDataTypeByType(type);
        }

        public static DotNetDataType GetDataTypeByType(Type type)
        {
            if (type == null)
                return DotNetDataType.UNKNOWN;

            if (typeof(Int16).Equals(type))
            {
                return DotNetDataType.Int32;
            }
            else if (typeof(UInt16).Equals(type))
            {
                return DotNetDataType.Int32;
            }
            else if (typeof(UInt32).Equals(type))
            {
                return DotNetDataType.Int32;
            }
            else if (typeof(int).Equals(type))
            {
                return DotNetDataType.Int32;
            }
            else if (typeof(UInt64).Equals(type))
            {
                return DotNetDataType.Int64;
            }
            else if (typeof(Int64).Equals(type))
            {
                return DotNetDataType.Int64;
            }
            else if (typeof(double).Equals(type))
            {
                return DotNetDataType.Double;
            }
            else if (typeof(bool).Equals(type))
            {
                return DotNetDataType.Boolean;
            }
            else if (typeof(char).Equals(type))
            {
                return DotNetDataType.Char;
            }
            else if (typeof(byte).Equals(type))
            {
                return DotNetDataType.Int32;
            }
            else if (typeof(DateTime).Equals(type))
            {
                return DotNetDataType.DateTime;
            }
            else if (typeof(float).Equals(type))
            {
                return DotNetDataType.Single;
            }
            else if (typeof(decimal).Equals(type))
            {
                return DotNetDataType.Decimal;
            }
            else if (typeof(string).Equals(type))
            {
                return DotNetDataType.String;
            }
            else if (typeof(byte[]).Equals(type))
            {
                return DotNetDataType.Byte;
            }
            else
            {
                return DotNetDataType.UNKNOWN;
            }
        }

        public static DotNetDataType GetDataTypeByTypeName(string datatype)
        {
            if (string.IsNullOrEmpty(datatype))
                return DotNetDataType.UNKNOWN;

            else if (datatype.Equals("System.UInt16", StringComparison.OrdinalIgnoreCase))
            {
                return DotNetDataType.Int32;
            }
            else if (datatype.Equals("System.Int16", StringComparison.OrdinalIgnoreCase))
            {
                return DotNetDataType.Int32;
            }
            else if (datatype.Equals("System.UInt32", StringComparison.OrdinalIgnoreCase))
            {
                return DotNetDataType.Int32;
            }
            else if (datatype.Equals("System.Int32", StringComparison.OrdinalIgnoreCase))
            {
                return DotNetDataType.Int32;
            }
            else if (datatype.Equals("UInt32", StringComparison.OrdinalIgnoreCase))
            {
                return DotNetDataType.Int32;
            }
            else if (datatype.Equals("Int32", StringComparison.OrdinalIgnoreCase))
            {
                return DotNetDataType.Int32;
            }
            else if (datatype.Equals("System.UInt64", StringComparison.OrdinalIgnoreCase))
            {
                return DotNetDataType.Int64;
            }
            else if (datatype.Equals("System.Int64", StringComparison.OrdinalIgnoreCase))
            {
                return DotNetDataType.Int64;
            }
            else if (datatype.Equals("UInt64", StringComparison.OrdinalIgnoreCase))
            {
                return DotNetDataType.Int64;
            }
            else if (datatype.Equals("Int64", StringComparison.OrdinalIgnoreCase))
            {
                return DotNetDataType.Int64;
            }
            else if (datatype.Equals("System.Double", StringComparison.OrdinalIgnoreCase))
            {
                return DotNetDataType.Double;
            }
            else if (datatype.Equals("Double", StringComparison.OrdinalIgnoreCase))
            {
                return DotNetDataType.Double;
            }
            else if (datatype.Equals("System.Boolean", StringComparison.OrdinalIgnoreCase))
            {
                return DotNetDataType.Boolean;
            }
            else if (datatype.Equals("Boolean", StringComparison.OrdinalIgnoreCase))
            {
                return DotNetDataType.Boolean;
            }
            else if (datatype.Equals("System.Char", StringComparison.OrdinalIgnoreCase))
            {
                return DotNetDataType.Char;
            }
            else if (datatype.Equals("Char", StringComparison.OrdinalIgnoreCase))
            {
                return DotNetDataType.Char;
            }
            else if (datatype.Equals("System.Byte", StringComparison.OrdinalIgnoreCase))
            {
                return DotNetDataType.Int32;
            }
            else if (datatype.Equals("Byte", StringComparison.OrdinalIgnoreCase))
            {
                return DotNetDataType.Int32;
            }
            else if (datatype.Equals("System.DateTime", StringComparison.OrdinalIgnoreCase))
            {
                return DotNetDataType.DateTime;
            }
            else if (datatype.Equals("DateTime", StringComparison.OrdinalIgnoreCase))
            {
                return DotNetDataType.DateTime;
            }
            else if (datatype.Equals("System.Float", StringComparison.OrdinalIgnoreCase))
            {
                return DotNetDataType.Single;
            }
            else if (datatype.Equals("Float", StringComparison.OrdinalIgnoreCase))
            {
                return DotNetDataType.Single;
            }
            else if (datatype.Equals("System.Single", StringComparison.OrdinalIgnoreCase))
            {
                return DotNetDataType.Single;
            }
            else if (datatype.Equals("Single", StringComparison.OrdinalIgnoreCase))
            {
                return DotNetDataType.Single;
            }
            else if (datatype.Equals("System.Decimal", StringComparison.OrdinalIgnoreCase))
            {
                return DotNetDataType.Decimal;
            }
            else if (datatype.Equals("Decimal", StringComparison.OrdinalIgnoreCase))
            {
                return DotNetDataType.Decimal;
            }
            else if (datatype.Equals("System.String", StringComparison.OrdinalIgnoreCase))
            {
                return DotNetDataType.String;
            }
            else if (datatype.Equals("String", StringComparison.OrdinalIgnoreCase))
            {
                return DotNetDataType.String;
            }
            else if (datatype.Equals("System.Byte[]", StringComparison.OrdinalIgnoreCase))
            {
                return DotNetDataType.Byte;
            }
            else if (datatype.Equals("Byte[]", StringComparison.OrdinalIgnoreCase))
            {
                return DotNetDataType.Byte;
            }
            else
            {
                return DotNetDataType.UNKNOWN;
            }
        }


        /// <summary>
        /// 取得域的类型
        /// </summary>
        /// <returns></returns>
        public static DotNetPropertyType GetPropertyType(Type type)
        {
            //注意 不能和orm通用，因为orm最终对象解析为binary 这里却是unknown

            if (type == null)
                return DotNetPropertyType.Unknown;

            if (type.IsEnum)
                return DotNetPropertyType.Enum;

            if (type.IsValueType || type.Equals(typeof(string)))
                return DotNetPropertyType.Value;

            if (type.IsInterface)
                return DotNetPropertyType.Interface;

            if (type.IsArray)
            {
                Type elementType = type.GetElementType();

                //byte[] 

                if (elementType.Equals(typeof(byte)))
                    return DotNetPropertyType.Binary;

                //???[]

                DotNetPropertyType elementfieldtype = GetPropertyType(elementType);

                switch (elementfieldtype)
                {
                    case DotNetPropertyType.Enum:
                        return DotNetPropertyType.EnumArray;
                    case DotNetPropertyType.Value:
                        return DotNetPropertyType.ValueArray;
                    case DotNetPropertyType.Object:
                        return DotNetPropertyType.ObjectArray;
                    case DotNetPropertyType.Interface:
                        return DotNetPropertyType.InterfaceArray;
                    default:
                        return DotNetPropertyType.Unknown;
                }
            }

            if (type.IsGenericType)
            {
                Type[] genericTypes = type.GetGenericArguments();

                if (genericTypes.Length != 1)
                    return DotNetPropertyType.Unknown;

                Type genericType = genericTypes[0];

                if (genericType.Equals(typeof(byte)))
                    return DotNetPropertyType.BinaryList;

                DotNetPropertyType genericFieldType = GetPropertyType(genericType);

                switch (genericFieldType)
                {
                    case DotNetPropertyType.Enum:
                        return DotNetPropertyType.EnumList;
                    case DotNetPropertyType.Value:
                        return DotNetPropertyType.ValueList;
                    case DotNetPropertyType.Object:
                        return DotNetPropertyType.ObjectList;
                    case DotNetPropertyType.Interface:
                        return DotNetPropertyType.InterfaceList;
                    default:
                        return DotNetPropertyType.Unknown;
                }
            }

            return DotNetPropertyType.Object;
        }


        public static bool Equals<T>(object from, object to)
        {
            return Equals<T>(from, to, null);
        }

        public static bool Equals<T>(object from, object to, string format)
        {
            if (from == null)
                return false;

            if (to == null)
                return false;

            switch (GetDataTypeByType(typeof(T)))
            {
                case DotNetDataType.String:
                    {
                        return string.Equals(from.ToString(), to.ToString(), StringComparison.OrdinalIgnoreCase);
                    }
                default:
                    {
                        T value = default(T);

                        if (!ParserHelper.TryParse<T>(from, out value, format))
                            return false;

                        T tvalue = default(T);

                        if (!ParserHelper.TryParse<T>(to, out tvalue, format))
                            return false;

                        return value.Equals(tvalue);
                    }
            }
        }


        public static new bool Equals(object from, object to)
        {
            return Equals(from, to, null);
        }

        public static bool Equals(object from, object to, string format)
        {
            Type parsetype = null;

            if (from == null && to == null)
                return false;
            else if (from == null)
                parsetype = to.GetType();
            else
                parsetype = from.GetType();

            return Equals(parsetype, from, to, format);
        }

        public static bool Equals(Type parsetype, object from, object to, string format)
        {
            if (parsetype == null)
                return false;

            if (from == null)
                return false;

            if (to == null)
                return false;

            switch (GetDataTypeByType(parsetype))
            {
                case DotNetDataType.String:
                    {
                        return string.Equals(from.ToString(), to.ToString(), StringComparison.OrdinalIgnoreCase);
                    }
                default:
                    {
                        object value = null;

                        if (!ParserHelper.TryParse(parsetype, from, out value, format))
                            return false;

                        object tvalue = null;

                        if (!ParserHelper.TryParse(parsetype, to, out tvalue, format))
                            return false;

                        return value.Equals(tvalue);
                    }
            }
        }


        public static bool Greater<T>(object from, object to)
        {
            return Greater<T>(from, to, null);
        }

        public static bool Greater<T>(object from, object to, string format)
        {
            return Greater(typeof(T), from, to, format);
        }

        public static bool Greater(object from, object to)
        {
            return Greater(from, to, null);
        }

        public static bool Greater(object from, object to, string format)
        {
            Type parsetype = null;

            if (from == null && to == null)
                return false;
            else if (from == null)
                parsetype = to.GetType();
            else
                parsetype = from.GetType();

            return Greater(parsetype, from, to, format);
        }

        public static bool Greater(Type parsetype, object from, object to, string format)
        {
            if (parsetype == null)
                return false;

            if (from == null)
                return false;

            if (to == null)
                return false;

            switch (GetDataTypeByType(parsetype))
            {

                case DotNetDataType.DateTime:
                    {
                        if (from == null)
                            return false;

                        if (to == null)
                            return false;

                        DateTime value;

                        DateTime tvalue;

                        if (string.IsNullOrEmpty(format))
                        {
                            if (!DateTime.TryParse(from.ToString(), out value))
                                return false;
                        }
                        else
                        {
                            if (!DateTime.TryParseExact(from.ToString(), format, CultureInfo.InstalledUICulture, DateTimeStyles.None, out value))
                                return false;
                        }

                        if (string.IsNullOrEmpty(format))
                        {
                            if (!DateTime.TryParse(to.ToString(), out tvalue))
                                return false;
                        }
                        else
                        {
                            if (!DateTime.TryParseExact(to.ToString(), format, CultureInfo.InstalledUICulture, DateTimeStyles.None, out tvalue))
                                return false;
                        }

                        return value > tvalue;
                    }
                case DotNetDataType.Decimal:
                case DotNetDataType.Double:
                case DotNetDataType.Int32:
                case DotNetDataType.Int64:
                case DotNetDataType.Single:
                    {
                        if (from == null)
                            return false;

                        if (to == null)
                            return false;

                        double value;

                        double tvalue;

                        if (!double.TryParse(from.ToString(), out value))
                            return false;

                        if (!double.TryParse(to.ToString(), out tvalue))
                            return false;

                        return value > tvalue;
                    }
                case DotNetDataType.Byte://binary
                case DotNetDataType.Char:
                case DotNetDataType.String:
                case DotNetDataType.Boolean:
                case DotNetDataType.Object:
                case DotNetDataType.UNKNOWN:
                default:
                    return false;
            }
        }


        public static bool TryParse<T>(object input, out T value)
        {
            return TryParse<T>(input, out value, null);
        }

        public static bool TryParse<T>(object input, out T value, string format)
        {
            value = default(T);

            object tempvalue = null;

            if (!TryParse(typeof(T), input, out tempvalue, format))
                return false;

            value = (T)tempvalue;

            return true;
        }

        public static bool TryParse(Type parsetype, object input, out object result, string format)
        {
            result = null;

            if (input == null)
                return false;

            Type type = parsetype;

            if (type.IsEnum)
            {
                try
                {
                    result = Enum.Parse(type, input.ToString().Trim());

                    //2010-02-18 bug!! 漏了返回！

                    return true;
                }
                catch
                {
                    return false;
                }
            }
            else if (type.Equals(typeof(byte)))
            {
                byte _value = byte.MinValue;

                if (!byte.TryParse(input.ToString(), out _value))
                    return false;

                result = _value;

                return true;
            }

            return TryParse(GetDataTypeByType(parsetype), input, out result, format);
        }

        public static bool TryParse(string parsetypename, object input, out object result, string format)
        {
            result = null;

            if (input == null)
                return false;

            return TryParse(GetDataTypeByTypeName(parsetypename), input, out result, format);
        }

        public static bool TryParse(DotNetDataType dotnettype, object input, out object result, string format)
        {
            result = null;

            if (input == null)
                return false;

            switch (dotnettype)
            {
                case DotNetDataType.Boolean:
                    {
                        bool _value = false;

                        if (!bool.TryParse(input.ToString(), out _value))
                            return false;

                        result = _value;

                        break;
                    }
                case DotNetDataType.Char:
                    {
                        char _value = char.MinValue;

                        if (!char.TryParse(input.ToString(), out _value))
                            return false;

                        result = _value;

                        break;
                    }
                case DotNetDataType.DateTime:
                    {
                        DateTime _value = DateTime.MinValue;

                        if (string.IsNullOrEmpty(format))
                        {
                            if (!DateTime.TryParse(input.ToString(), out _value))
                                return false;
                        }
                        else
                        {
                            if (!DateTime.TryParseExact(input.ToString(), format, CultureInfo.InstalledUICulture, DateTimeStyles.None, out _value))
                                return false;
                        }

                        result = _value;

                        break;
                    }
                case DotNetDataType.Decimal:
                    {
                        decimal _value = decimal.MinValue;

                        if (!decimal.TryParse(input.ToString(), out _value))
                            return false;

                        result = _value;

                        break;
                    }
                case DotNetDataType.Double:
                    {
                        double _value = double.MinValue;

                        if (!double.TryParse(input.ToString(), out _value))
                            return false;

                        result = _value;

                        break;
                    }
                case DotNetDataType.Int32:
                    {
                        int _value = int.MinValue;

                        if (!int.TryParse(input.ToString(), out _value))
                            return false;

                        result = _value;

                        break;
                    }
                case DotNetDataType.Int64:
                    {
                        Int64 _value = Int64.MinValue;

                        if (!Int64.TryParse(input.ToString(), out _value))
                            return false;

                        result = _value;

                        break;
                    }
                case DotNetDataType.Single:
                    {
                        float _value = float.MinValue;

                        if (!float.TryParse(input.ToString(), out _value))
                            return false;

                        result = _value;

                        break;
                    }
                case DotNetDataType.String:
                    {
                        result = input.ToString();

                        break;
                    }
                case DotNetDataType.Byte:
                    {
                        if (!input.GetType().Equals(typeof(byte[])))
                            return false;

                        result = input;

                        break;
                    }
                case DotNetDataType.Object:
                case DotNetDataType.UNKNOWN:
                default:
                    {
                        result = input;

                        break;
                    }
            }

            return true;
        }


        public static bool TryParse(object input, out int value)
        {
            value = int.MinValue;

            if (!int.TryParse(input.ToString(), out value))
                return false;

            return true;
        }

        public static bool TryParse(object input, out Int64 value)
        {
            value = Int64.MinValue;

            if (!Int64.TryParse(input.ToString(), out value))
                return false;

            return true;
        }

        public static bool TryParse(object input, out bool value)
        {
            value = false;

            if (!bool.TryParse(input.ToString(), out value))
                return false;

            return true;
        }

        public static bool TryParse(object input, out float value)
        {
            value = float.MinValue;

            if (!float.TryParse(input.ToString(), out value))
                return false;

            return true;
        }

        public static bool TryParse(object input, out double value)
        {
            value = double.MinValue;

            if (!double.TryParse(input.ToString(), out value))
                return false;

            return true;
        }

        public static bool TryParse(object input, out byte value)
        {
            value = byte.MinValue;

            if (!byte.TryParse(input.ToString(), out value))
                return false;

            return true;
        }

        public static bool TryParse(object input, out char value)
        {
            value = char.MinValue;

            if (!char.TryParse(input.ToString(), out value))
                return false;

            return true;
        }

        public static bool TryParse(object input, out DateTime value)
        {
            value = DateTime.MinValue;

            if (!DateTime.TryParse(input.ToString(), out value))
                return false;

            return true;
        }

        public static bool TryParse(object input, out decimal value)
        {
            value = decimal.MinValue;

            if (!decimal.TryParse(input.ToString(), out value))
                return false;

            return true;
        }



        public static T Parse<T>(object input)
        {
            T value = default(T);

            TryParse<T>(input, out value);

            return value;
        }

        public static object Parse(Type type, object input, string format)
        {
            object result = null;
            TryParse(type, input, out result, format);
            return result;
        }

        public static object Parse(DotNetDataType dotnettype, object input, string format)
        {
            object result = null;
            TryParse(dotnettype, input, out result, format);
            return result;
        }


        public static object GetNullValue(Type type)
        {
            object nullValue = GetNullValue(GetDataTypeByTypeName(type.Name));

            //10-08-29 解决枚举问题

            if (nullValue == null && type.IsEnum)
                return Enum.ToObject(type, 0);

            return nullValue;
        }

        public static object GetNullValue(DotNetDataType datatype)
        {
            switch (datatype)
            {
                case DotNetDataType.Boolean:
                    return default(bool);

                case DotNetDataType.Byte:
                    return new byte[] { };

                case DotNetDataType.Char:
                    return default(char);

                case DotNetDataType.DateTime:
                    return default(DateTime);

                case DotNetDataType.Decimal:
                    return default(decimal);

                case DotNetDataType.Double:
                    return default(double);

                case DotNetDataType.Int32:
                    return default(Int32);

                case DotNetDataType.Int64:
                    return default(Int64);

                case DotNetDataType.Single:
                    return default(Single);

                case DotNetDataType.String:
                    return default(string);

                default:
                    return null;
            }
        }

        public static object GetMinNullValue(Type type)
        {
            switch (GetDataTypeByTypeName(type.Name))
            {
                case DotNetDataType.Boolean:
                    return false;

                case DotNetDataType.Byte:
                    return new byte[] { };

                case DotNetDataType.Char:
                    return char.MinValue;

                case DotNetDataType.DateTime:
                    return DateTime.MinValue;

                case DotNetDataType.Decimal:
                    return decimal.MinValue;

                case DotNetDataType.Double:
                    return double.MinValue;

                case DotNetDataType.Int32:
                    return Int32.MinValue;

                case DotNetDataType.Int64:
                    return Int64.MinValue;

                case DotNetDataType.Single:
                    return Single.MinValue;

                case DotNetDataType.String:
                    return String.Empty;

                default:
                    return null;
            }
        }

        private void test001()
        {
            Console.WriteLine(typeof(char).FullName);
            Console.WriteLine(typeof(string).FullName);
            Console.WriteLine(typeof(int).FullName);
            Console.WriteLine(typeof(Int32).FullName);
            Console.WriteLine(typeof(Single).FullName);
            Console.WriteLine(typeof(double).FullName);
            Console.WriteLine(typeof(Int64).FullName);
            Console.WriteLine(typeof(byte).FullName);
            Console.WriteLine(typeof(bool).FullName);
            Console.WriteLine(typeof(decimal).FullName);
            Console.WriteLine(typeof(DateTime).FullName);
            Console.WriteLine(typeof(byte[]).FullName);
            Console.WriteLine(typeof(uint).FullName);
        }

        private void test002()
        {
            Console.WriteLine(GetDataTypeByTypeName(typeof(char).FullName).ToString());
            Console.WriteLine(GetDataTypeByTypeName(typeof(string).FullName).ToString());
            Console.WriteLine(GetDataTypeByTypeName(typeof(int).FullName).ToString());
            Console.WriteLine(GetDataTypeByTypeName(typeof(Int32).FullName).ToString());
            Console.WriteLine(GetDataTypeByTypeName(typeof(Single).FullName).ToString());
            Console.WriteLine(GetDataTypeByTypeName(typeof(double).FullName).ToString());
            Console.WriteLine(GetDataTypeByTypeName(typeof(Int64).FullName).ToString());
            Console.WriteLine(GetDataTypeByTypeName(typeof(byte).FullName).ToString());
            Console.WriteLine(GetDataTypeByTypeName(typeof(bool).FullName).ToString());
            Console.WriteLine(GetDataTypeByTypeName(typeof(decimal).FullName).ToString());
            Console.WriteLine(GetDataTypeByTypeName(typeof(DateTime).FullName).ToString());
            Console.WriteLine(GetDataTypeByTypeName(typeof(byte[]).FullName).ToString());

            Console.WriteLine(GetDataTypeByTypeName(typeof(char).Name).ToString());
            Console.WriteLine(GetDataTypeByTypeName(typeof(string).Name).ToString());
            Console.WriteLine(GetDataTypeByTypeName(typeof(int).Name).ToString());
            Console.WriteLine(GetDataTypeByTypeName(typeof(Int32).Name).ToString());
            Console.WriteLine(GetDataTypeByTypeName(typeof(Single).Name).ToString());
            Console.WriteLine(GetDataTypeByTypeName(typeof(double).Name).ToString());
            Console.WriteLine(GetDataTypeByTypeName(typeof(Int64).Name).ToString());
            Console.WriteLine(GetDataTypeByTypeName(typeof(byte).Name).ToString());
            Console.WriteLine(GetDataTypeByTypeName(typeof(bool).Name).ToString());
            Console.WriteLine(GetDataTypeByTypeName(typeof(decimal).Name).ToString());
            Console.WriteLine(GetDataTypeByTypeName(typeof(DateTime).Name).ToString());
            Console.WriteLine(GetDataTypeByTypeName(typeof(byte[]).Name).ToString());
        }

        private void test003()
        {
            Console.WriteLine(GetDataTypeByType(typeof(char)).ToString());
            Console.WriteLine(GetDataTypeByType(typeof(string)).ToString());
            Console.WriteLine(GetDataTypeByType(typeof(int)).ToString());
            Console.WriteLine(GetDataTypeByType(typeof(Int32)).ToString());
            Console.WriteLine(GetDataTypeByType(typeof(Single)).ToString());
            Console.WriteLine(GetDataTypeByType(typeof(double)).ToString());
            Console.WriteLine(GetDataTypeByType(typeof(Int64)).ToString());
            Console.WriteLine(GetDataTypeByType(typeof(byte)).ToString());
            Console.WriteLine(GetDataTypeByType(typeof(bool)).ToString());
            Console.WriteLine(GetDataTypeByType(typeof(decimal)).ToString());
            Console.WriteLine(GetDataTypeByType(typeof(DateTime)).ToString());
            Console.WriteLine(GetDataTypeByType(typeof(byte[])).ToString());
            Console.WriteLine(GetDataTypeByType(typeof(uint)).ToString());
            Console.WriteLine(GetDataTypeByType(typeof(UInt16)).ToString());
            Console.WriteLine(GetDataTypeByType(typeof(UInt32)).ToString());
            Console.WriteLine(GetDataTypeByType(typeof(UInt64)).ToString());

        }

        private void test004()
        {
            char _char = char.MinValue;
            string _string = "";
            int _int = int.MinValue;
            Int32 _Int32 = Int32.MinValue;
            Single _Single = Single.MinValue;
            double _double = double.MinValue;
            Int64 _Int64 = Int64.MinValue;
            byte _byte = byte.MinValue;
            bool _bool = false;
            decimal _decimal = decimal.MinValue;
            DateTime _DateTime = DateTime.MinValue;
            byte[] _bytes = new byte[] { };

            Console.WriteLine(GetDataType(_char).ToString());
            Console.WriteLine(GetDataType(_string).ToString());
            Console.WriteLine(GetDataType(_int).ToString());
            Console.WriteLine(GetDataType(_Int32).ToString());
            Console.WriteLine(GetDataType(_Single).ToString());
            Console.WriteLine(GetDataType(_double).ToString());
            Console.WriteLine(GetDataType(_Int64).ToString());
            Console.WriteLine(GetDataType(_byte).ToString());
            Console.WriteLine(GetDataType(_bool).ToString());
            Console.WriteLine(GetDataType(_decimal).ToString());
            Console.WriteLine(GetDataType(_DateTime).ToString());
            Console.WriteLine(GetDataType(_bytes).ToString());

        }

        private void test005()
        {
            object result = null;

            Console.WriteLine(TryParse(typeof(byte), "123", out result, null));
            result = (byte)result;
            Console.WriteLine(TryParse(typeof(string), "123", out result, null));
            result = (string)result;
            Console.WriteLine(TryParse(typeof(int), "123", out result, null));
            result = (int)result;
            Console.WriteLine(TryParse(typeof(Int32), "123", out result, null));
            result = (Int32)result;
            Console.WriteLine(TryParse(typeof(Single), "0.123", out result, null));
            result = (Single)result;
            Console.WriteLine(TryParse(typeof(double), "0.123", out result, null));
            result = (double)result;
            Console.WriteLine(TryParse(typeof(Int64), "123", out result, null));
            result = (Int64)result;
            Console.WriteLine(TryParse(typeof(bool), "false", out result, null));
            result = (bool)result;
            Console.WriteLine(TryParse(typeof(decimal), "0.123", out result, null));
            result = (decimal)result;
            Console.WriteLine(TryParse(typeof(byte[]), new byte[] { }, out result, null));
            result = (byte[])result;
            Console.WriteLine(TryParse(typeof(DateTime), "2010-01-03", out result, null));
            result = (DateTime)result;
        }

        private void test006()
        {
            string value = "2010-01-01";

            Console.WriteLine(TypeDescriptor.GetConverter(typeof(DateTime)).ConvertFrom(value));
            Console.WriteLine(TypeDescriptor.GetConverter(typeof(DateTime)).ConvertFrom(value).GetType().Name);
        }

    }
}
